# -*- coding:utf-8 -*-
# @Time : 2021-2-1 15:51
# @Author : suny570
# @Site   :
# @File : semantic_client.py
# @Software: PyCharm

#from app import app, root_path, semantic_faq
from app import app, root_path
from app.Logging import init_logger
import os
import json
import time
from json import JSONDecodeError
from flask import request, jsonify
from src.db_es.ElasticSearchClass import ElasticSearchClass
from src.intelligent_interaction.engine.loginfo_engine import LoginfoEngine
from src.intelligent_interaction.engine.semantic_search import SemanticSearch
import src.db_es.es_config as Config
from src.db_es.es_config import ES_Config
from src.intelligent_interaction.engine.similarity_search import SimilaritySearch

logger = init_logger(root_path + '/Logs/semantic_faq_')
es_config = ES_Config()

@app.route('/semantic_kg', methods=['POST'])
def semantic_search():
    # 测试版本
    es_service_conn = ElasticSearchClass(es_config.env_names['test']['HOST'], es_config.env_names['test']['PORT'],
                                         es_config.env_names['test']['USER'], es_config.env_names['test']['PASSWORD'])
    # 正式版本
    # es_service_conn = ElasticSearchClass(es_config.env_names['product']['HOST'], es_config.env_names['product']['PORT'],
    #                                      es_config.env_names['product']['USER'], es_config.env_names['product']['PASSWORD'])

    loginfo_engine = LoginfoEngine(es_service_conn, es_config)
    log_data, data = {}, {}
    try:
        data = json.loads(request.get_data())
        log_data['id'] = None
        log_data['ip'] = str(request.remote_addr)
        log_data['query_info'] = str(data)
        log_data['service_name'] = "semantic_faq"
        log_data['time'] = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

        content = data["query"]
        #print(str(data.keys()))
        if "pro_id" in list(data.keys()):
            pro_id = data["pro_id"]
        else:
            pro_id = ''

        if len(content) == 0:
            return_data = {"failDetail": '搜索文本长度为零，请输入要查询的内容。'}
            recognize_info = {"code": "0001", "message": "失败", "data": return_data}
            logger.warning(recognize_info)
            log_data['code'] = "0001"
            log_data['message'] = "失败"
            log_data['ret_data'] = str(return_data)
            loginfo_engine.write_search_info_into_es(data, log_data)

        else:
            if len(content) > 128:
                content = content[0:127]
            # 搜索策略
            semantic_faq = SemanticSearch(es_service_conn)
            if pro_id in list(es_config.index_names['province'].keys()):
                # 演示版本
                #print("pro_id is {}".format(pro_id))
                if pro_id == 't9':
                    ret_json = semantic_faq.standard_search_inter_epri(es_config.index_names['province'][pro_id],
                                                                       es_config.type_names['type'], data, pro_id, 10)
                else:
                    ret_json = semantic_faq.standard_search_inter(es_config.index_names['province'][pro_id],
                                                                  es_config.type_names['type'], data,  pro_id, 10)
            else:
                ret_json = semantic_faq.standard_search_inter(es_config.index_names['stand']['index'],
                                                              es_config.type_names['type'], data, pro_id, 10)

            if len(ret_json) > 0:
                return_data = ret_json
                recognize_info = {"code": "0000", "message": "成功", "data": return_data}
                log_data['code'] = "0000"
                log_data['message'] = "成功"
                log_data['ret_data'] = str(return_data)
                logger.info(recognize_info)

                loginfo_engine.write_search_info_into_es(data, log_data)

            else:
                return_data = {"failDetail": '没有查询到结果，请尝试其他检索词，输入内容为{}。'.format(len(content))}
                recognize_info = {"code": "0004", "message": "失败", "data": return_data}
                logger.warning(recognize_info)
                log_data['code'] = "0004"
                log_data['message'] = "失败"
                log_data['ret_data'] = str(return_data)
                loginfo_engine.write_search_info_into_es(data, log_data)

    except JSONDecodeError as e:
        error_info = {"error": "输入数据格式错误,具体如下：{}".format(e.msg)}
        recognize_info = {"code": "0002", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0002"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_info_into_es(data, log_data)
        es_service_conn.close_connect()

    except Exception as e:
        error_info = {"error": "服务异常,具体如下：{0}".format(repr(e))}
        recognize_info = {"code": "0003", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0003"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_info_into_es(data, log_data)
        es_service_conn.close_connect()

    es_service_conn.close_connect()
    return jsonify(recognize_info), 200

@app.route('/semantic_hot_top', methods=['POST'])
def semantic_hot_top():
    """
    热点搜索接口
    数据从ES获取，设置更新时间，一个小时一次，自动加到系统中
    :return:
    """
    # ES引擎正式
    es_service_conn = ElasticSearchClass(es_config.env_names['test']['HOST'], es_config.env_names['test']['PORT'],
                                          es_config.env_names['test']['USER'], es_config.env_names['test']['PASSWORD'])
    #loginfo_engine = LoginfoEngine(es_service_conn)  # 日志引擎
    log_data, data = {}, {}
    try:

        # with open(os.getcwd() + '/src/hot_top.txt', 'r', encoding='utf-8') as f:
        #     for l in f.readlines():
        #         temp = {}
        #         temp['id'] = l.strip().split('|')[0]
        #         temp['standard_question'] = l.strip().split('|')[1]
        #         ret_json.append(temp)
        data = json.loads(request.get_data())
        # content = data["query"]
        if "pro_id" in list(data.keys()):
            pro_id = data["pro_id"]
        else:
            pro_id = ''

        log_data['id'] = None
        log_data['ip'] = str(request.remote_addr)
        log_data['query_info'] = ''
        log_data['service_name'] = "semantic_hot"
        log_data['time'] = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        semantic_faq = SemanticSearch(es_service_conn)
        if pro_id in list(es_config.index_names['province'].keys()):
            ret_json = semantic_faq.hottop_search_es_inter(es_config.index_names['province'][pro_id],
                                                           es_config.type_names['type'], 10)
        else:
            ret_json = semantic_faq.hottop_search_es_inter(es_config.index_names['stand']['index'],
                                                           es_config.type_names['type'], 10)
        return_data = ret_json

        recognize_info = {"code": "0000", "message": "成功", "data": return_data}
        log_data['code'] = "0000"
        log_data['message'] = "成功"
        log_data['ret_data'] = str(return_data)
        logger.info(recognize_info)
        #loginfo_engine.write_search_info_into_es(data, log_data)

    except JSONDecodeError as e:
        error_info = {"error": "服务异常,具体如下：{}".format(e.msg)}
        recognize_info = {"code": "0002", "message": "失败", "data": error_info}  # 返回内容
        logger.warning(recognize_info)
        log_data['code'] = "0002"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        es_service_conn.close_connect()

    es_service_conn.close_connect()
    return jsonify(recognize_info), 200

@app.route('/simi_search', methods=['POST'])
def semantic_simi_search():
    es_service_conn = ElasticSearchClass(es_config.env_names['test']['HOST'], es_config.env_names['test']['PORT'],
                                         es_config.env_names['test']['USER'], es_config.env_names['test']['PASSWORD'])
    loginfo_engine = LoginfoEngine(es_service_conn, es_config)
    log_data, data = {}, {}
    try:
        data = json.loads(request.get_data())
        log_data['id'] = None
        log_data['ip'] = str(request.remote_addr)
        log_data['query_info'] = str(data)
        log_data['service_name'] = "simi_search"
        log_data['time'] = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        # print(str(data))
        content = data["title"]
        if "pro_id" in list(data.keys()):
            pro_id = data["pro_id"]
        else:
            pro_id = ''

        if content is None or len(content) == 0:
            content = data["query"]
            data["title"] = content
        if len(content) == 0:
            return_data = {"failDetail": '搜索文本长度为零，请输入要查询的内容。'}
            recognize_info = {"code": "0001", "message": "失败", "data": return_data}
            logger.warning(recognize_info)
            log_data['code'] = "0001"
            log_data['message'] = "失败"
            log_data['ret_data'] = str(return_data)
            loginfo_engine.write_search_news_info_into_es(data, log_data)

        else:
            if len(content) > 128:
                content = content[0:127]
            # 相似内容搜索
            simi_search = SimilaritySearch(es_service_conn)

            if pro_id in list(es_config.index_names['province'].keys()):
                ret_json = simi_search.simi_search_inter(es_config.index_names['province'][pro_id],
                                                         es_config.type_names['type'], data, 'question', 10)
            else:
                ret_json = simi_search.simi_search_inter(es_config.index_names['news']['index'],
                                                         es_config.type_names['type'], data, 'title', 10)

            if len(ret_json) > 0:
                return_data = ret_json
                recognize_info = {"code": "0000", "message": "成功", "data": return_data}
                log_data['code'] = "0000"
                log_data['message'] = "成功"
                log_data['ret_data'] = str(return_data)
                logger.info(recognize_info)

                loginfo_engine.write_search_news_info_into_es(data, log_data)

            else:
                return_data = {"failDetail": '没有查询到结果，输入内容为{}。'.format(len(content))}
                recognize_info = {"code": "0004", "message": "失败", "data": return_data}
                logger.warning(recognize_info)
                log_data['code'] = "0004"
                log_data['message'] = "失败"
                log_data['ret_data'] = str(return_data)
                logger.info(recognize_info)
                loginfo_engine.write_search_news_info_into_es(data, log_data)

    except JSONDecodeError as e:
        error_info = {"error": "输入数据格式错误,具体如下：{}".format(e.msg)}
        recognize_info = {"code": "0002", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0002"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_news_info_into_es(data, log_data)
        es_service_conn.close_connect()

    except Exception as e:
        error_info = {"error": "服务异常,具体如下：{0}".format(repr(e))}
        recognize_info = {"code": "0003", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0003"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_news_info_into_es(data, log_data)
        es_service_conn.close_connect()

    es_service_conn.close_connect()
    return jsonify(recognize_info), 200

@app.route('/simi_search_click', methods=['POST'])
def semantic_simi_search_click():
    es_service_conn = ElasticSearchClass(es_config.env_names['test']['HOST'], es_config.env_names['test']['PORT'],
                                          es_config.env_names['test']['USER'], es_config.env_names['test']['PASSWORD'])

    loginfo_engine = LoginfoEngine(es_service_conn, es_config)
    log_data, data = {}, {}
    try:
        data = json.loads(request.get_data())
        log_data['id'] = None
        log_data['ip'] = str(request.remote_addr)
        log_data['query_info'] = str(data)
        log_data['service_name'] = "simi_search_click"
        log_data['time'] = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        content = data["title"]
        if "pro_id" in list(data.keys()):
            pro_id = data["pro_id"]
        else:
            pro_id = ''

        if content is None or len(content) == 0:
            content = data["query"]
            data["title"] = content
        if len(content) == 0:
            return_data = {"failDetail": '搜索文本长度为零，请输入要查询的内容。'}
            recognize_info = {"code": "0001", "message": "失败", "data": return_data}
            logger.warning(recognize_info)
            log_data['code'] = "0001"
            log_data['message'] = "失败"
            log_data['ret_data'] = str(return_data)
            loginfo_engine.write_search_news_info_into_es(data, log_data)

        else:
            if len(content) > 128:
                content = content[0:127]
            # 相似内容搜索
            simi_search = SimilaritySearch(es_service_conn)
            if pro_id in list(es_config.index_names['province'].keys()):
                ret_init_doc, ret_json = simi_search.simi_search_list_click(es_config.index_names['province'][pro_id],
                                                                            es_config.type_names['type'], data,
                                                                            'question', 10)
            else:
                ret_init_doc, ret_json = simi_search.simi_search_list_click(es_config.index_names['news']['index'],
                                                                            es_config.type_names['type'], data,
                                                                            'title', 10)
            if len(ret_json) > 0:
                return_data = ret_json
                recognize_info = {"code": "0000", "message": "成功", "data_init": ret_init_doc, "data": return_data}
                log_data['code'] = "0000"
                log_data['message'] = "成功"
                log_data['ret_data'] = str([ret_init_doc,return_data])
                logger.info(recognize_info)

                loginfo_engine.write_search_news_info_into_es(data, log_data)

            else:
                return_data = {"failDetail": '没有查询到结果，输入内容为{}。'.format(len(content))}
                recognize_info = {"code": "0004", "message": "失败", "data": return_data}
                logger.warning(recognize_info)
                log_data['code'] = "0004"
                log_data['message'] = "失败"
                log_data['ret_data'] = str(return_data)
                logger.info(recognize_info)
                loginfo_engine.write_search_news_info_into_es(data, log_data)

    except JSONDecodeError as e:
        error_info = {"error": "输入数据格式错误,具体如下：{}".format(e.msg)}
        recognize_info = {"code": "0002", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0002"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_news_info_into_es(data, log_data)
        es_service_conn.close_connect()

    except Exception as e:
        error_info = {"error": "服务异常,具体如下：{0}".format(repr(e))}
        recognize_info = {"code": "0003", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0003"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_news_info_into_es(data, log_data)
        es_service_conn.close_connect()

    es_service_conn.close_connect()
    return jsonify(recognize_info), 200

"""新增数据检测"""
@app.route('/input_data_detection', methods=['POST'])
def data_detection():
    es_service_conn = ElasticSearchClass(es_config.env_names['test']['HOST'], es_config.env_names['test']['PORT'],
                                          es_config.env_names['test']['USER'], es_config.env_names['test']['PASSWORD'])

    loginfo_engine = LoginfoEngine(es_service_conn, es_config)
    log_data, data = {}, {}
    try:
        data = json.loads(request.get_data())
        log_data['id'] = None
        log_data['ip'] = str(request.remote_addr)
        log_data['query_info'] = str(data)
        log_data['service_name'] = "input_data_detection"
        log_data['time'] = str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

        data["query"] = data["title"]
        if "pro_id" in list(data.keys()):
            pro_id = data["pro_id"]
        else:
            pro_id = ''
        question = data["title"]
        answer = data['content']

        if len(question) == 0:
            return_data = {"failDetail": '输入标题内容为空'}
            recognize_info = {"code": "0001", "message": "失败", "data": return_data}
            logger.warning(recognize_info)
            log_data['code'] = "0001"
            log_data['message'] = "失败"
            log_data['ret_data'] = str(return_data)
            loginfo_engine.write_search_info_into_es(data, log_data)

        elif len(answer) == 0:
            return_data = {"failDetail": '输入答案内容为空'}
            recognize_info = {"code": "0001", "message": "失败", "data": return_data}
            logger.warning(recognize_info)
            log_data['code'] = "0001"
            log_data['message'] = "失败"
            log_data['ret_data'] = str(return_data)
            loginfo_engine.write_search_info_into_es(data, log_data)

        else:
            if len(question) > 128:
                content = question[0:127]
            # 搜索策略
            semantic_faq = SemanticSearch(es_service_conn)
            if pro_id in list(es_config.index_names['province'].keys()):
                ret_json = semantic_faq.data_detection(es_config.index_names['province'][pro_id],
                                                       es_config.type_names['type'], data, 4, 0.25, 0.25)
            else:
                ret_json = semantic_faq.data_detection(es_config.index_names['stand']['index'],
                                                       es_config.type_names['type'], data, 4, 0.25, 0.25)

            if len(ret_json) > 0:
                return_data = ret_json
                recognize_info = {"code": "0000", "message": "成功", "data": return_data}
                log_data['code'] = "0000"
                log_data['message'] = "成功"
                log_data['ret_data'] = str(return_data)
                logger.info(recognize_info)
                loginfo_engine.write_search_info_into_es(data, log_data)

            else:
                return_data = {"info": '数据库没有相似数据'}
                recognize_info = {"code": "0004", "message": "失败", "data": return_data}
                logger.warning(recognize_info)
                log_data['code'] = "0004"
                log_data['message'] = "失败"
                log_data['ret_data'] = str(return_data)
                logger.info(recognize_info)
                loginfo_engine.write_search_info_into_es(data, log_data)

    except JSONDecodeError as e:
        error_info = {"error": "输入数据格式错误,具体如下：{}".format(e.msg)}
        recognize_info = {"code": "0002", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0002"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_info_into_es(data, log_data)
        es_service_conn.close_connect()

    except Exception as e:
        error_info = {"error": "服务异常,具体如下：{0}".format(repr(e))}
        recognize_info = {"code": "0003", "message": "失败", "data": error_info}
        logger.warning(recognize_info)
        log_data['code'] = "0003"
        log_data['message'] = "失败"
        log_data['ret_data'] = str(error_info)
        loginfo_engine.write_search_info_into_es(data, log_data)
        es_service_conn.close_connect()

    es_service_conn.close_connect()
    return jsonify(recognize_info), 200